/*
 * @Description: 用户服务
 * @Author: Haor
 * @Date: 2022-04-03 00:21:16
 * @LastEditTime: 2022-08-01 21:43:36
 * @LastEditors: Haor
 */

import { Injectable, HttpException } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { getRepository, Repository } from "typeorm";
import { User } from 'src/entities/user.entity'
import { DepartmentEntity } from 'src/entities/department.entity'
import { HttpResult } from '@libs/http.result'
import { format } from '@utils/date'
import { Logger } from '@utils/log4'
import { EnableStatusEnum } from '@enumerations/common.enumeration'
import { BusinessException, SignException } from "@exceptions";
import { QueryUserByRoleDto } from "@dto/query-user.dto";
import { PagerDto } from '@dto/public.dto'
import { SnowflakeId } from "@libs/snowflake.id";
import { listUnderlineKeyToHump } from "@utils/data";
import { CreateUserDto, UpdateUserDto, ListByDeptDto, QueryListDTO } from "@dto/user.dto";
import { ServerException } from "@utils/exception";
import { tryCatch } from "rxjs/internal-compatibility";
import { CatchError } from "@decorators/cache-error.decorator";

// 获取用户密码
interface GetUserPassword {
	userName?: string
	userId?: number
}

@Injectable()
export class UserService {
	constructor(
		@InjectRepository(User)
		private readonly userRepository: Repository<User>
	) {}

	/**
	 * 创建用户
	 * @param {CreateUserDto} createUserDto 参数
	 * @returns
	 */
	async create(createUserDto: CreateUserDto) {
		try {
            const isExistUser = await this.userRepository.findOne({
                userName: createUserDto.userName
            })
            if (isExistUser) {
                Logger.warn('用户已存在！')
                throw new BusinessException('用户已存在')
            } else {
                const newUser = await this.userRepository.create(createUserDto)
                newUser.id = SnowflakeId.generate()
                newUser.createBy = '张学友'
                newUser.createTime = format(new Date())
                const saveRes = await this.userRepository.save(newUser)
                console.log(`新增用户【${newUser.userName}】成功！`)
                return HttpResult.success(saveRes)
            }
        } catch (e) {
            ServerException(e)
        }
	}

    /**
     * 根据角色获取用户列表
     * @param {String} roleId 角色id
     */
    getUserListByRole(role: QueryUserByRoleDto) {
        const randomTotal = Math.floor(Math.random() * 200)
        const userList = new Array(randomTotal).fill(null).map((itm, idx) => {
            return {
                id: role.roleId + '_' + idx,
                roleName: 'test' + idx
            }
        })
        return HttpResult.pageData({
            list: userList,
            total: 30
        })
	}

	/**
	 * 部门id
	 * @param {ListByDeptDto} data
	 */
	async getUserListByDept(data: ListByDeptDto) {
	    try {
            const queryListSql = `
            SELECT
                u.user_name,
                u.id,
                u.nick_name,
                u.auth_group_id,
                u.create_time 
            FROM
                sys_user u
                LEFT JOIN sys_dept d ON u.dept_id = d.id 
            WHERE
				d.id=${data.deptId}
				AND u.is_delete=0
            LIMIT ${data.pageIndex === 1 ? 0 : data.pageIndex * data.pageSize},
            ${data.pageSize}`;
            const countSql = `SELECT count(*) as count FROM sys_user u LEFT JOIN sys_dept d ON u.dept_id = d.id WHERE d.id=${data.deptId};`
            const list = await this.userRepository.query(queryListSql)
            const [total] = await this.userRepository.query(countSql)
            return HttpResult.pageData({ total: total ? +total.count : 0, list: listUnderlineKeyToHump(list) })
        } catch (e) {
            ServerException(e)
        }
	}

    /**
     * 查询多个用户
     * @param {QueryListDTO} data
     */
    async queryUserList(data: QueryListDTO) {
        try {
            // const queryWhereList: Array<string> = ['u.is_delete = :isDelete']
            // if (data.createStart) {
            //     queryWhereList.push(`u.create_time >= :createStart`)
            // }
            // if (data.createEnd) {
            //     queryWhereList.push(`u.create_time <= :createEnd`)
            // }
            // if (data.deptId) {
            //     queryWhereList.push(`u.dept_id = :deptId`)
            // }
            // const queryWhere = queryWhereList.join(' AND ')
            // const [list, total]: [Array<User>, number] = await this.userRepository
            //     .createQueryBuilder('u')
            //     .leftJoinAndSelect(DepartmentEntity, 'dept', 'u.dept_id=dept.id')
            //     .where(queryWhere, {
            //         keyword: `%${data.keyword}%`,
            //         createStart: data.createStart,
            //         createEnd: data.createEnd,
            //         deptId: data.deptId,
            //         isDelete: 0
            //     })
            //     .orWhere(`u.nick_name LIKE :keyword OR u.user_name LIKE :keyword`, {
            //         keyword: `%${data.keyword}%`
            //     })
            //     .skip((data.pageIndex - 1) * data.pageSize)
            //     .take(data.pageSize)
            //     .orderBy('u.create_time', 'DESC')
            //     .getManyAndCount()
            // return HttpResult.pageData({list, total})

            const [total, list] = await this.userRepository.findAndCount({
                relations: ['department']
            })
            console.log(list)

            return HttpResult.success(1)
        } catch (e) {
            ServerException(e)
        }
    }

    /**
     * 通过用户id查询用户
     * @param userId
     */
    getUserById(userId: number): Promise<User> {
        return this.userRepository.findOne({
            where: {
                id: userId
            }
        })
    }

	/**
	 * 查询单个用户
	 * @param id  用户id
	 * @returns
	 */
    @CatchError('用户id查询用户')
	async findOne(id: number) {
        const user = await this.userRepository.findOne({
            id: id
        })
        if (!user) {
            throw new BusinessException('用户不存在')
        }
        return HttpResult.success(user)
	}

    /**
     * 通过用户名和密码获取用户信息
     * @param {string} userName
     * @param {string} password
     * @return {Promise<User>} user
     */
	async getUserByNameAndPassword(userName: string, password: string): Promise<User> {
	    return this.userRepository.findOne({
            where: {
                userName,
                password
            }
        })
    }

	/**
	 * 通过用户名查找用户
	 * @param {String} userName 用户名称
	 * @return {Promise<User|null>}
	 */
	async getUserByName(userName: string): Promise<User | null> {
		return new Promise(async (resolve) => {
			const user = await this.userRepository.findOne({
				userName: userName
			})
			if (user === null) return resolve(null)
			return resolve(user)
		})
	}

	/**
	 * 获取用户密码
	 * @param {Object} getParams
	 * @return {Promise<string>}
	 */
	async getUserPassword(getParams: GetUserPassword): Promise<string> {
		return new Promise(async (resolve) => {
			const findUser = await this.userRepository.findOne({
				select: ['password'],
				where: [{ id: getParams.userId }, { userName: getParams.userName }]
			})
			if (!findUser) return resolve('')
			return resolve(findUser.password)
		})
	}

	/**
	 * 更新用户
	 * @param id 用户id
	 * @param updateUserDto
	 * @returns
	 */
	update(id: number, updateUserDto: UpdateUserDto) {
		return `This action updates a #${id} user`
	}

	/**
	 * 删除用户
	 * @param id
	 */
	@CatchError('根据用户id删除用户')
	async remove(id: number) {
        const { affected } = await this.userRepository.update(
            { id: id },
            {
                enabled: EnableStatusEnum.disabled
            }
        )
        if (!affected) {
            throw new BusinessException('删除用户失败')
        }
        return HttpResult.success()
	}
}
